#include "board.h"   
#include "bsp_gpio.h"   

#define GPIO_PORT 	0 
#define GPIO_MODE   1 
#define GPIO_IO 	2 

uint32_t gpioCofig[][3] = 
{
	{(GPIO_TypeDef *)GPIOC,GPIO_Mode_Out_PP,GPIO_Pin_13},	//	RS485_EN  
	{(GPIO_TypeDef *)GPIOA,GPIO_Mode_IN_FLOATING,GPIO_Pin_4},			//	D  
	{(GPIO_TypeDef *)GPIOA,GPIO_Mode_IPD,GPIO_Pin_7},			//	Y 
	{(GPIO_TypeDef *)GPIOB,GPIO_Mode_IPD,GPIO_Pin_0},			//	A2
	{(GPIO_TypeDef *)GPIOB,GPIO_Mode_IPD,GPIO_Pin_12},		//	B2
	{(GPIO_TypeDef *)GPIOB,GPIO_Mode_Out_PP,GPIO_Pin_13},	//	LED
	{(GPIO_TypeDef *)GPIOB,GPIO_Mode_IPD,GPIO_Pin_8},			//	A1
	{(GPIO_TypeDef *)GPIOB,GPIO_Mode_IPD,GPIO_Pin_9},			//	B1
	
};


extern _Main_t mainPar;

/*函数声明*/  
//void static motorXmTick(void);
//void static motorCdTick(void);
void motorTick(u8 *mode,uint32_t *Pulse,u8 *state,u8 *dir,u8 gpioEn,u8 gpioDir,u8 gpioStep,u8 stopMin,u8 StopMax);

/*
gpio:需要控制的GPIO，需要在枚举表中定义对应的值
*/
void GpioSet(uint8_t gpio,uint8_t state)
{
//	rt_enter_critical();
	if(state == 0) 
	{
		GPIO_ResetBits((GPIO_TypeDef *)gpioCofig[gpio][GPIO_PORT],gpioCofig[gpio][GPIO_IO]);
	}
	else {
		GPIO_SetBits((GPIO_TypeDef *)gpioCofig[gpio][GPIO_PORT],gpioCofig[gpio][GPIO_IO]);
	}
//	rt_exit_critical();

}
/*
gpio:获取对于GPIO的状态
*/
uint8_t GpioGet(uint8_t gpio)
{

	return GPIO_ReadInputDataBit((GPIO_TypeDef *)gpioCofig[gpio][GPIO_PORT],gpioCofig[gpio][GPIO_IO]);


}
 /**
  * @brief  初始化控制LED的IO
  * @param  无
  * @retval 无
  */
void GPIO_Config(void)
{		
		/*定义一个GPIO_InitTypeDef类型的结构体*/
		GPIO_InitTypeDef GPIO_InitStructure;
		u8 RegNum = sizeof(gpioCofig)/3/4;

		/*开启LED相关的GPIO外设时钟*/
		RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |  RCC_APB2Periph_GPIOC  | RCC_APB2Periph_GPIOD  | RCC_APB2Periph_GPIOE , ENABLE);
		//禁用JTAG功能，释放PB3/PB4引脚
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
		GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

		while ( RegNum  > 0)
		{
			RegNum -- ;
			/*选择要控制的GPIO引脚*/
			GPIO_InitStructure.GPIO_Pin = gpioCofig[RegNum][GPIO_IO];	
			
			/*设置引脚模式为通用推挽输出*/
			GPIO_InitStructure.GPIO_Mode = gpioCofig[RegNum][GPIO_MODE];   
			
						/*设置引脚速率为50MHz */   
			GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
				
						/*调用库函数，初始化GPIO*/
			GPIO_Init((GPIO_TypeDef *)gpioCofig[RegNum][GPIO_PORT], &GPIO_InitStructure);	
			
			GPIO_SetBits((GPIO_TypeDef *)gpioCofig[RegNum][GPIO_PORT],gpioCofig[RegNum][GPIO_IO]);
		
		}
		
		GpioSet(RS485_EN,0);

}
void gpio_set_dir(uint8_t gpio,uint32_t GMODE)
{
		GPIO_InitTypeDef GPIO_InitStructure;

		/*开启LED相关的GPIO外设时钟*/
		RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |  RCC_APB2Periph_GPIOC  | RCC_APB2Periph_GPIOD  | RCC_APB2Periph_GPIOE , ENABLE);

		GPIO_InitStructure.GPIO_Pin = gpioCofig[gpio][GPIO_IO];	

		/*设置引脚模式为通用推挽输出*/
		GPIO_InitStructure.GPIO_Mode = GMODE;   

//				/*设置引脚速率为50MHz */   
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 

				/*调用库函数，初始化GPIO*/
		GPIO_Init((GPIO_TypeDef *)gpioCofig[gpio][GPIO_PORT], &GPIO_InitStructure);	


}

//通用定时器中断初始化
//这里时钟选择为APB1的2倍，而APB1为36M
//arr：自动重装值。
//psc：时钟预分频数
//这里使用的是定时器3!
void TIM4_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能

	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 计数到50为5ms
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  100Khz的计数频率  
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
 
	TIM_ITConfig(  //使能或者失能指定的TIM中断
		TIM4, //TIM2
		TIM_IT_Update ,
		ENABLE  //使能
		);
	NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

	TIM_Cmd(TIM4, ENABLE);  //使能TIMx外设
	TIM_Cmd(TIM4, DISABLE);  
							 
}
void TIM4_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 
		{
		TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源
		}
}
//通用定时器中断初始化
//这里时钟选择为APB1的2倍，而APB1为36M
//arr：自动重装值。
//psc：时钟预分频数
//这里使用的是定时器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能

	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值	 计数到50为5ms
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值  100Khz的计数频率  
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
 
	TIM_ITConfig(  //使能或者失能指定的TIM中断
		TIM3, //TIM2
		TIM_IT_Update ,
		ENABLE  //使能
		);
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

	TIM_Cmd(TIM3, ENABLE);  //使能TIMx外设					 
}


void EXTIX_Init(void)
{
 
 	EXTI_InitTypeDef EXTI_InitStructure;
 	NVIC_InitTypeDef NVIC_InitStructure;

  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);	//使能复用功能时钟

    //GPIOA.6 中断线以及中断初始化配置   下降沿触发
  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource4);

  	EXTI_InitStructure.EXTI_Line=EXTI_Line4;	
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;		//上升沿触发
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  	EXTI_Init(&EXTI_InitStructure);	 	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器


  	NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;			//使能按键WK_UP所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;	//抢占优先级2， 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;					//子优先级3
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure); 

}
//	rt_enter_critical();
//	rt_exit_critical();
//外部中断6服务程序
uint16_t D_channel_count=0;//Dzhou计数
void EXTI4_IRQHandler(void)
{

	if(EXTI_GetITStatus(EXTI_Line4) == SET)   // key2
	{      
		D_channel_count++;			
	}
	EXTI_ClearITPendingBit(EXTI_Line4);    // Clear the EXTI line 5 pending bit   
}


void Data_update(void)
{
	static uint16_t ABY_DATA=0;
	uint8_t bit0,bit1,bit2,bit3,bit4;
	bit0 = GpioGet(A1_channel);
	bit1 = GpioGet(A2_channel);
	bit2 = GpioGet(B1_channel);
	bit3 = GpioGet(B2_channel);
	bit4 = GpioGet(Y_channel);

	ABY_DATA = bit4<<4|bit3<<3|bit2<<2|bit1<<1|bit0;
	
	writeMdodbusReg(MReg_D,D_channel_count); 
	writeMdodbusReg(MReg_ABY,ABY_DATA); 

}

